﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using log4net;
using CashFlow.Db.DAL;
using CashFlow.Db.Entity;
using SysAdmin._00_Def;

namespace SysAdmin._03_Service._00_Db
{
    public class FeeService
    {
        public static IList<FeeAndUserInfoView> QueryByWhere(string date
            , string name)
        {
            using (var db = SqlSugarHelper.GetDb())
            {
                var query = db.Queryable<FeeEntity>()
                        .InnerJoin<ShopInfoEntity>((f, u) => f.UserId == u.Id)
                        .OrderByDescending((f, u) => f.Date);

                if (!string.IsNullOrEmpty(date))
                {
                    query = query.Where((f, u) => f.Date == date);
                }
                if (!string.IsNullOrEmpty(name))
                {
                    query = query.Where((f, u) => u.Name.Contains(name));
                }

                var ls = query.Select((f, u) => new FeeAndUserInfoView
                {
                    Fee = f,
                    UserInfo = u
                }).ToList();
                return ls;
            }
        }

        public static void CalcAllFee(string date)
        {
            var orders = OrderService.QueryAllOrders2(date);
            if (orders.Count == 0)
            {
                return;
            }

            var ls3 = new List<FeeItemData>();
            var users = UserService.QueryAllUsers().Select(x => x.UserInfo).ToList();
            var ls = new List<CalcItemData>();

            #region 计算用户订单数和直推订单数
            foreach (var item in users)
            {
                var cid = new CalcItemData();
                cid.UserInfo = item;
                var order5 = orders.Where(x => x.BuyerUserId == item.Id).FirstOrDefault();
                cid.Amount = order5 != null ? order5.Amount : 0;

                var ls2 = users.Where(x => x.ReferenceInvitationCode == item.InvitationCode).ToList();
                foreach (var item2 in ls2)
                {
                    var fcui = new FirstGenerationChildUserInfo();
                    fcui.UserInfo = item2;
                    var order3 = orders.Where(x => x.BuyerUserId == item2.Id).FirstOrDefault();
                    if (order3 != null)
                    {
                        fcui.Amoumt = order3.Amount;
                    }
                    var childUserIds = GetAllChildUserIds(item2, users);
                    decimal sum2 = 0M;
                    int sum3 = 0;
                    foreach (var item3 in childUserIds)
                    {
                        var order4 = orders.Where(x => x.BuyerUserId == item3).FirstOrDefault();
                        if (order4 != null)
                        {
                            sum2 += order4.Amount;
                            sum3++;
                        }
                    }
                    fcui.AllChildUserOrderAmountSum = sum2;
                    fcui.AllChildUserOrderCount = sum3;
                    fcui.ChildUserIdList = childUserIds;

                    cid.FirstGenerationChildUserInfo.Add(fcui);
                }

                ls2.Clear();
                ls.Add(cid);
            }
            #endregion

            #region 计算各种费用
            foreach (var item in ls)
            {
                decimal orderPrefit = item.Amount * 0.01M;
                decimal shopManagerFee = 0;
                decimal bonusFee = 0;

                int orderTotal = item.Amount > 0 ? 1 : 0;
                foreach (var item2 in item.FirstGenerationChildUserInfo)
                {
                    orderTotal += item2.Amoumt > 0 ? 1 : 0;
                    orderTotal += item2.AllChildUserOrderCount;
                }
                decimal percent = GetShopManagerLevelPercent(orderTotal);
                shopManagerFee += percent * item.Amount;
                foreach (var item2 in item.FirstGenerationChildUserInfo)
                {
                    int orderTotal2 = (item2.Amoumt > 0 ? 1 : 0) + item2.AllChildUserOrderCount;
                    decimal sum2 = item2.Amoumt + item2.AllChildUserOrderAmountSum;
                    var percent2 = GetShopManagerLevelPercent(orderTotal2);
                    var percentDifference = percent - percent2;
                    if (percentDifference > 0)
                    {
                        decimal tmp = sum2 * (percent - percent2);
                        shopManagerFee += tmp;
                    }
                    else
                    {
                        if (percent == 0.01M && percent2 == 0.01M)
                        {
                            bool bFlag = true; // 是否应该拿直推的业绩分红0.003

                            var ls6 = users
                                .Where(x => x.ReferenceInvitationCode == item2.UserInfo.InvitationCode)
                                .ToList();
                            foreach (var item6 in ls6)
                            {
                                var ls7 = GetAllChildUserIds(item6, users);
                                if (ls7.Count >= 31)
                                {
                                    bFlag = false;
                                    break;
                                }
                                else if (ls7.Count >= 30)
                                {
                                    int count2 = orders.Count(x => ls7.Contains(x.BuyerUserId));
                                    count2 += item2.Amoumt > 0 ? 1 : 0;
                                    if (count2 >= 31)
                                    {
                                        bFlag = false;
                                        break;
                                    }
                                }
                            }

                            if (bFlag)
                            {
                                bonusFee += sum2 * 0.003M;
                            }
                        }
                    }
                }

                ls3.Add(new FeeItemData
                {
                    BonusFee = bonusFee,
                    OrderPrefitFee = orderPrefit,
                    ShopManagerFee = shopManagerFee,
                    UserInfo = item.UserInfo
                });
            }
            #endregion

            #region 计算寄售服务费
            foreach (var item in ls3)
            {
                int count = 0;
                decimal sum = 0M;
                var item2 = ls.Where(x => x.UserInfo.Id == item.UserInfo.Id).FirstOrDefault();
                count += item2.Amount > 0 ? 1 : 0;
                sum += item2.Amount;
                foreach (var item3 in item2.FirstGenerationChildUserInfo)
                {
                    count += item3.Amoumt > 0 ? 1 : 0;
                    count += item3.AllChildUserOrderCount;
                    sum += item3.Amoumt;
                    sum += item3.AllChildUserOrderAmountSum;
                }
                var percent = GetShopManagerLevelPercent(count);
                var consignmentSaleFee = sum * (0.015M - percent);
                if (percent == 0.01M)   // 除去名下所有人的平台分红
                {
                    IList<int> userIds = GetAllChildUserIds(item.UserInfo, users);
                    decimal sum2 = ls3.Where(x => userIds.Contains(x.UserInfo.Id)).Sum(x => x.BonusFee);
                    sum2 += item.BonusFee;
                    consignmentSaleFee -= sum2;
                }
                item.ConsignmentSaleFee = consignmentSaleFee;
            }
            #endregion

            #region 更新到数据库
            using (var db = SqlSugarHelper.GetDb())
            {
                StringBuilder sb = new StringBuilder();
                foreach (var item in ls3)
                {
                    var entity = db.Queryable<FeeEntity>().Where(x => x.UserId == item.UserInfo.Id && x.Date == date).First();
                    if (entity != null)
                    {
                        string sql = string.Format("update Fee set OrderProfitFee = {0}, ShopManagerFee = {1}, BoundFee = {2}, ConsignmentSaleFee = {3} where UserId = {4} and Date = '{5}';"
                            , item.OrderPrefitFee
                            , item.ShopManagerFee
                            , item.BonusFee
                            , item.ConsignmentSaleFee
                            , item.UserInfo.Id
                            , date);
                        sb.Append(sql);
                    }
                    else
                    {
                        string sql = string.Format("insert into Fee(UserId, Date, OrderProfitFee, ShopManagerFee, BoundFee, ConsignmentSaleFee) values({0}, '{1}', {2}, {3}, {4}, {5});"
                            , item.UserInfo.Id
                            , date
                            , item.OrderPrefitFee
                            , item.ShopManagerFee
                            , item.BonusFee
                            , item.ConsignmentSaleFee);
                        sb.Append(sql);
                    }
                }
                string sql2 = sb.ToString();
                if (!string.IsNullOrEmpty(sql2))
                {
                    db.Ado.ExecuteCommand(sql2);
                }
            }
            #endregion

            ls.Clear();
            ls3.Clear();
            users.Clear();
            orders.Clear();
        }

        private static IList<int> GetAllChildUserIds(UserInfoEntity userInfo
            , IList<UserInfoEntity> users)
        {
            var childUserIds = new List<int>();
            var queue = new Queue<string>();
            queue.Enqueue(userInfo.InvitationCode);
            while (queue.Count > 0)
            {
                string code = queue.Dequeue();
                var ls2 = users.Where(x => x.ReferenceInvitationCode == code).ToList();
                foreach (var item3 in ls2)
                {
                    childUserIds.Add(item3.Id);
                    queue.Enqueue(item3.InvitationCode);
                }
            }
            return childUserIds;
        }

        private static decimal GetShopManagerLevelPercent(int orderCount)
        {
            if (orderCount >= 0 && orderCount < 2)
            {
                return 0M;
            }
            else if (orderCount >= 2 && orderCount < 6)
            {
                return 0.005M;
            }
            else if (orderCount >= 6 && orderCount < 11)
            {
                return 0.006M;
            }
            else if (orderCount >= 11 && orderCount < 21)
            {
                return 0.007M;
            }
            else if (orderCount >= 21 && orderCount < 31)
            {
                return 0.008M;
            }
            else if (orderCount >= 31)
            {
                return 0.01M;
            }

            return 0M;
        }

        public class FeeItemData
        {
            public UserInfoEntity UserInfo { get; set; }
            public decimal OrderPrefitFee { get; set; }
            public decimal ShopManagerFee { get; set; }
            public decimal BonusFee { get; set; }
            public decimal ConsignmentSaleFee { get; set; }
        }

        public class CalcItemData
        {
            public UserInfoEntity UserInfo { get; set; }
            public decimal Amount { get; set; }
            public IList<FirstGenerationChildUserInfo> FirstGenerationChildUserInfo { get; set; }
                = new List<FirstGenerationChildUserInfo>();
        }

        public class FirstGenerationChildUserInfo
        {
            public UserInfoEntity UserInfo { get; set; }
            public decimal Amoumt { get; set; }
            public IList<int> ChildUserIdList { get; set; }
            public decimal AllChildUserOrderAmountSum { get; set; }
            public int AllChildUserOrderCount { get; set; }
        }

    }
}
